home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / sml_nj / 93src.lha / src / runtime / mac / MacOS.dep.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-02-09  |  12.3 KB  |  578 lines

  1. /* MacOS.dep.c */
  2. /* 31Dec91  e  */
  3. /* 10Dec92  e  for SML/NJ 92 */
  4. /* 30Dec92  e  fixed "no apname" bug */
  5.  
  6. /* A MacOS version of Signals and Sbrk for ML */
  7.  
  8. #include "MacOS.dep.h"
  9. #include "os_mac.h"
  10.  
  11. #include <errno.h>
  12. #include <stdlib.h>
  13. #include <unix.h>
  14. #include <fcntl.h>
  15. #include <console.h>
  16. #include <string.h>
  17. #include <console.h>
  18.  
  19. /* portions derived from: M68.dep.c
  20.  *
  21.  * COPYRIGHT (c) 1990 by AT&T Bell Laboratories.
  22.  *
  23.  * M68 dependent code for the SML/NJ runtime kernel.
  24.  */
  25.  
  26. #include "ml_os.h"
  27. #include "ml_state.h"
  28. #include "request.h"
  29.  
  30. #include "tags.h"
  31. #include "ml_types.h"
  32.  
  33. #include <sysEqu.h>        /* for CurrentA5 */
  34. #include <Dialogs.h>
  35. #include <Memory.h>
  36. #include <Events.h>
  37. #include <Files.h>
  38. #include <StandardFile.h>
  39. #undef  SystemSixOrLater
  40. #define SystemSixOrLater 1
  41. #include <OSUtils.h>
  42.  
  43. extern void cecho2file(char *, int, FILE *);
  44. extern long _ftype, _fcreator;
  45. extern int    arenasize;
  46. extern int    isExported;
  47.  
  48. int mac_sbrk_done = FALSE;
  49. int mac_brkpt = 0;
  50. int mac_blimt = 0;
  51.  
  52. char usual_prefix[] = ":";
  53. char *prefix = usual_prefix;
  54.  
  55. jmp_buf restartJmpBuf;
  56.  
  57. /** Define trap numbers **/
  58.  
  59. #ifndef _Unimplemented
  60. #define _Unimplemented    0xA89F    /* Unimplemented trap    */
  61. #endif
  62.  
  63. #ifndef _SysEnvirons
  64. #define _SysEnvirons    0xA090    /* SysEnvirons Inquiry    */
  65. #endif
  66.  
  67. static char *eargv[4];
  68. static char apname[64];
  69.  
  70. #if 0
  71.  
  72. short homeRefNum;
  73.  
  74. short getHome(void)    {
  75.     IOParam pb;
  76.     char buf[256];
  77.     
  78.     pb.ioNamePtr = (StringPtr)buf;
  79.     pb.ioVRefNum = 0;
  80.     PBGetVolSync((ParmBlkPtr)&pb);
  81.     return(homeRefNum = pb.ioVRefNum);
  82. }
  83.  
  84. void setHome(short refnum)    {
  85.     IOParam pb;
  86.     
  87.     pb.ioNamePtr = 0;
  88.     pb.ioVRefNum = refnum;
  89.     PBSetVolSync((ParmBlkPtr)&pb);
  90. }
  91.  
  92. #else /* 08Jan93  e  -- for chdir */
  93.  
  94. static short dfltWDVRefNum;
  95. static short homeWDVRefNum;
  96. static long  dfltWDDirID;
  97. static long  homeWDDirID;
  98.  
  99. static void getHome(void)    {
  100.     WDPBRec pb;
  101.     
  102.     pb.ioNamePtr = 0;
  103.     pb.ioCompletion = 0;
  104.     PBHGetVolSync(&pb);
  105.     dfltWDVRefNum = homeWDVRefNum = pb.ioWDVRefNum;
  106.     dfltWDDirID = homeWDDirID = pb.ioWDDirID;
  107. }
  108.  
  109. static void setupDfltDir(void)    {
  110.     WDPBRec pb;
  111.     
  112.     pb.ioNamePtr = 0;
  113.     pb.ioCompletion = 0;
  114.     pb.ioVRefNum = dfltWDVRefNum;
  115.     pb.ioWDDirID = dfltWDDirID;
  116.     PBHSetVolSync(&pb);
  117. }
  118.  
  119. static void setupHomeDir(void)    {
  120.     WDPBRec pb;
  121.     
  122.     pb.ioNamePtr = 0;
  123.     pb.ioCompletion = 0;
  124.     pb.ioVRefNum = homeWDVRefNum;
  125.     pb.ioWDDirID = homeWDDirID;
  126.     PBHSetVolSync(&pb);
  127. }
  128.  
  129. #endif
  130.  
  131. int mac_init( char ***p_argv )
  132. {
  133.     SysEnvRec sysenv;
  134.     KeyMap kMap;
  135.     long len;
  136.     short err, err2;
  137.     short refNum;
  138.     
  139.     /* make sure System 6 or later is running */
  140.     if ( GetTrapAddress(_SysEnvirons) == GetTrapAddress(_Unimplemented) )
  141.         die("SMLeNJ requires at least System 6");
  142.     /* make sure it's a M68020+ and has an FPU */
  143.     SysEnvirons( curSysEnvVers, &sysenv );
  144.     if ( (sysenv.processor < env68020) || (!sysenv.hasFPU) )
  145.         die("SMLeNJ requires at least a M68020 and FPU");
  146.     /* added this line for Soren/Quadra...   10Feb92  e  */
  147.     SetApplLimit((void *)(((long )&sysenv)-32768L-2000L));
  148.     /* find the home directory */
  149.     getHome();
  150.     setjmp(restartJmpBuf);
  151.     arenasize = 0;
  152.     isExported = 0;
  153.     prefix = usual_prefix;
  154.     _ftype = 'SMLi';
  155.     _fcreator = 'NJML';
  156.     sprintf(apname, "Ñ%#s", CurApName);                /* magic bullet Ñ to prevent prefix */
  157.     thinkc_workaround();   /* see cstruct.c */
  158.     /* err = HOpenDF( homeRefNum, 0, (unsigned char *)CurApName, fsRdPerm, &refNum ); 08Jan93 e */
  159.     err = HOpenDF( dfltWDVRefNum, dfltWDDirID, (unsigned char *)CurApName, fsRdPerm, &refNum );
  160.     if ( err == noErr )
  161.     { err2 = GetEOF( refNum, &len );
  162.       FSClose( refNum );
  163.       if ( err2 == noErr && len > 500000 )
  164.       { GetKeys( kMap );
  165.         if ( ! ( kMap[1] & 4 ) )
  166.         { /* option key not down */
  167.           chatting( "[Loading SML core image]\n");    /* note: NEEDED for console_init() */
  168.           eargv[0] = apname;
  169.           eargv[1] = "-i";
  170.           eargv[2] = apname;
  171.           eargv[3] = 0;
  172.           *p_argv = eargv;
  173.           return 3;
  174.         }
  175.       }
  176.     }
  177.     return ccommand(p_argv);
  178. }
  179.  
  180. static char *
  181. strcatbut(/* char *s1, const char *s2 */)
  182. {
  183.     asm {
  184.         movea.l    4(sp),a0        ;  A0 = s1
  185.         movea.l    8(sp),a1        ;  A1 = s2
  186.         clr.l    d0                ;  oops, otherwise d0 might never be set - 7Jan92 
  187. @1        tst.b    (a0)+
  188.         bne.s    @1
  189.         subq.l    #1,a0
  190. @2        move.b    (a1)+,d1        ;  D1.B = char
  191.         cmpi.b    #'.',d1
  192.         bne.s    @3
  193.         move.l    a1,d0            ;  D0.L = addr of last '.'
  194.         subq.l    #1,d0
  195.         cmpi.b    #'.',(a1)
  196.         bne.s    @4
  197.         addq.l    #1,a1
  198.         bra.s    @2
  199. @3        cmpi.b    #'/',d1
  200.         bne.s    @4
  201.         moveq    #':',d1
  202. @4        move.b    d1,(a0)+
  203.         bne.s    @2
  204.     }
  205. }
  206.  
  207. extern unsigned char * __c2p(register const char *s, register char *t);
  208.  
  209. int chdir( char *dn ) {
  210.     WDPBRec pb;
  211.     char cbuf[256];
  212.     char pbuf[256];
  213.     short err;
  214.  
  215.     if((strlen(prefix)+strlen(dn)) > 255) {
  216.         errno = EDOM;
  217.         return -1;
  218.     }
  219.     /* keep this translation consistent with that done in eopen below */
  220.     if ( strchr( dn, ':' ) ) {
  221.         __c2p( dn, pbuf );
  222.     }
  223.     else {
  224.         if ( *dn == 'Ñ' ) {
  225.             dfltWDVRefNum = homeWDVRefNum;
  226.             dfltWDDirID = homeWDDirID;
  227.               dn++;
  228.         }
  229.         if ( *dn == '/' ) { *cbuf = 0; dn++; }
  230.         else strcpy( cbuf, prefix );
  231.         strcatbut( cbuf, dn );
  232.         __c2p( cbuf, pbuf );
  233.     }
  234.     pb.ioNamePtr = (StringPtr )pbuf;
  235.     pb.ioCompletion = 0;
  236.     pb.ioVRefNum = dfltWDVRefNum;
  237.     pb.ioWDDirID = dfltWDDirID;
  238.     err = PBHSetVolSync(&pb);
  239.     if ( err == noErr )
  240.     {    pb.ioNamePtr = 0;
  241.         pb.ioCompletion = 0;
  242.         PBHGetVolSync(&pb);
  243.         {    if ( err == noErr )
  244.             dfltWDVRefNum = pb.ioWDVRefNum;
  245.             dfltWDDirID = pb.ioWDDirID;
  246.             return 0;
  247.         }
  248.     }
  249.     return -1;
  250. }
  251.  
  252. /* 4Feb93  e  */
  253. OSType e_getfiletype( char *fn )
  254. {    FInfo finf;
  255.     Str255 pn;
  256.     
  257.     __c2p( fn, (char *)pn );
  258.     if ( HGetFInfo( 0, 0L, pn, &finf ) == noErr )
  259.         return finf.fdType;
  260.     else
  261.         return (OSType )'?!?!';
  262. }
  263.  
  264. char *texttypes[] = { ".sig", ".sml", ".s", ".txt", ".lex", ".grm", "" };
  265.  
  266. int eopen(char *fn, int mode)
  267.     {
  268.     char buf[256];
  269.     char *p, **q;
  270.     int res;
  271.     
  272.     /* 08Jan93  e  -- new pathname translation */
  273.     /* keep this translation consistent with that done in chdir above */
  274.     if((strlen(prefix)+strlen(fn)) > 255) {
  275.         errno = EDOM;
  276.         return -1;
  277.     }
  278.     setupDfltDir();
  279.     if ( strchr(fn,':') ) {
  280.         strcpy(buf, fn);
  281.         p=strrchr(buf,'.');
  282.     }
  283.     else {
  284.         if ( *fn == 'Ñ' ) {
  285.             setupHomeDir();
  286.             if(!strcmp(fn,apname)) _ftype = 'APPL';
  287.               fn++;
  288.         }
  289.         if ( *fn == '/' ) { *buf = 0; fn++; }
  290.         else strcpy(buf, prefix);
  291.         p = strcatbut(buf,fn);
  292.     }
  293. #if 0
  294.     if (p) {
  295.         if     (!strcmp(p,".sig")) mode |= O_TEXT;
  296.         else if(!strcmp(p,".sml")) mode |= O_TEXT;
  297.         else if(!strcmp(p,".s"))   mode |= O_TEXT;
  298.         else if(!strcmp(p,".txt")) mode |= O_TEXT;
  299.         else if(!strcmp(p,".lex")) mode |= O_TEXT;
  300.         else if(!strcmp(p,".grm")) mode |= O_TEXT;
  301.     }
  302. #else
  303.     /* 4Feb93  e  */
  304.     if ( ( ( ! p ) || strcmp( p, ".mo" ) ) && e_getfiletype( buf ) == 'TEXT' )
  305.          mode |= O_TEXT;
  306.     else if (p) {
  307.         for ( q = &texttypes[0]; **q != '\0'; q++ )
  308.             if ( ! strcmp( p, *q ) ) mode |= O_TEXT;
  309.     }
  310. #endif
  311.     if (mode & O_TEXT) _ftype = 'TEXT';
  312.     res = open(buf, mode);
  313.     _ftype = 'SMLi';
  314.     return res;
  315. }
  316.  
  317. #if 0
  318.  
  319. static Point putWhere = { 106, 104 };
  320.  
  321. /* dribble was... [didn't work!?]
  322.             {
  323.             char **av;
  324.             int ac;
  325.             ac = ccommand(&av);
  326.             }
  327.             break;
  328. */
  329.  
  330. void doDribble(void)
  331.     {
  332.     SFReply reply;
  333.     char buf[256];
  334.     IOParam pb;
  335.     
  336.     /*  present dialog  */
  337.     SFPutFile(putWhere, (ConstStr255Param)"", (ConstStr255Param)"", (DlgHookProcPtr)NULL, &reply);
  338.     if (reply.good) {
  339.         /*  redirect stdout  */
  340.         /* setfile((char *) scratch.fName, &scratch); */
  341.         setHome(reply.vRefNum);
  342.         /* sprintf(buf, "%#s", reply.fName); */
  343.         cecho2file((char *) reply.fName, 0, stdout);
  344.         setHome(homeRefNum);
  345.     }
  346. }
  347.  
  348. #endif
  349.  
  350. void nalert(char *s)
  351. {
  352.     register int i;
  353.     char p0[255];
  354.     p0[0] = (char) strlen(s);
  355.     strcpy(p0+1,s);
  356.     for(i=1;i<255;i++)
  357.         if (p0[i] == '\n') p0[i] = '\r';
  358.         
  359.     InitCursor();        /* get standard arrow cursor */
  360.     ParamText((ConstStr255Param)p0,"\p","\p","\p");
  361.     NoteAlert((short )ok_alertID,0L);
  362. }
  363.  
  364. void eDoDialog(int sel)
  365. {
  366.     
  367.     switch(sel) {
  368.       case 0: {
  369.         DialogPtr dlg;
  370.         short i;
  371.         /* do About */
  372.         /* SetDAFont(helvetica); */
  373.         dlg=GetNewDialog(about_dlogID,NULL,(WindowPtr)(-1L));
  374.         ModalDialog((ModalFilterProcPtr)NULL,&i);
  375.         DisposDialog(dlg);
  376.         /* SetDAFont(systemFont); */
  377.         break;
  378.         }
  379.       case 1: {
  380.         char s[64];
  381.         sprintf(s,"Heap size is %ldk.\n\nPartition size is %ldk.",
  382.                   arenasize/1024L, (mac_blimt - mac_brkpt)/1024L);
  383.         nalert(s);
  384.         break;
  385.         }
  386. #if 0
  387.       case 2: {
  388.         doDribble();
  389.         break;
  390.         }
  391. #endif
  392.     }
  393. }
  394.  
  395. /*  Sbrk */
  396. /**
  397.  ** This implements sbrk/brk using MacOS.
  398.  ** it is based on the mach implementation in callgc.c
  399.  ** 01Jan92  e
  400.  **/
  401.  
  402. int sbrk(incr)
  403.     int incr;
  404. {
  405.     Size largestSz, cangrowSz;
  406.     Ptr mptr;
  407.  
  408.     if (incr)
  409.         die("sbrk called with nonzero value");
  410.     if (mac_sbrk_done == FALSE) {
  411.         MaxApplZone();    /* expand the heap */
  412.         largestSz = MaxMem(&cangrowSz);
  413.         cangrowSz = largestSz + cangrowSz - 393216L;
  414.         /*384L*1024L=393216=384k for runtime system*/
  415.         if(!(mptr = NewPtr(cangrowSz)))
  416.             die("sbrk cannot allocate: %dK", cangrowSz/1024);
  417.         mac_brkpt = ((int)(mptr + 8191) & -8192); /* make it a "page" boundary */
  418.         mac_blimt =  (int)(mptr + cangrowSz);
  419.         mac_sbrk_done = TRUE;
  420.     }
  421.     return(mac_brkpt);
  422. }
  423.  
  424. int brk(pos)
  425.     int pos;
  426. {
  427.     if (pos > mac_blimt)
  428.     return TRUE;
  429.     else
  430.     return FALSE;
  431. }
  432.  
  433. int getpagesize()    {
  434.     return(8192);
  435. }
  436.  
  437. int get_edata()    {
  438.     return((mac_blimt + 8191) & -8192);
  439. }
  440.  
  441. int get_etext()    {
  442.     die("get_etext: not done yet!");
  443.     return(0);
  444. }
  445.  
  446. /* signals */
  447.  
  448. static __sig_func_e e_sig[__NSIG_e+1];
  449.  
  450. void
  451. e_raise_guts(struct sigcontext *scp)
  452. {
  453.     __sig_func_e f;
  454.     int i = scp->sig;
  455.     
  456.     if (i <= 0 || i > __NSIG_e) {
  457.         errno = EINVAL;
  458.         return;
  459.     }
  460.     f = e_sig[i];
  461.     if (f != SIG_IGN_e) {
  462.         /* e_sig[i] = SIG_DFL_e; */
  463.         if (f == SIG_DFL_e)
  464.             _exit(0);
  465.         (*f)(i, (scp->code & 0x0fff), scp);
  466.     }
  467. }
  468.  
  469. void
  470. init_TRAPS();
  471. void
  472. handleTRAP()
  473.     {
  474.     asm {
  475. @handleTRAP:                        ; rewritten to handle Virtual Memory -- 10Feb92  e
  476.         MOVE.L    #SIGTRAP, -(SP)        ; push sig
  477.         MOVEM.L    D0-D7/A0-A6, -(SP)    ;  push 15 regs
  478.         MOVE.L    SP, -(SP)            ;   push sig context ptr
  479.         MOVE.L    CurrentA5, A5        ;    for C variable access
  480.         JSR        e_raise_guts        ;    called in supervisor mode!!!!!
  481.         ADDQ.L    #4, SP                ;   drop sig context ptr
  482.         MOVEM.L    (SP)+, D0-D7/A0-A6    ;  pop  15 regs
  483.         ADDQ.L    #4, SP                ; drop sig
  484.         RTE                            ; return
  485.         ;
  486. @handleFPU:                            ; added to handle M68882 FPU EXC_PEND -- 12Feb92  e
  487.         MOVE.L    #SIGTRAP, -(SP)        ; push sig
  488.         MOVEM.L    D0-D7/A0-A6, -(SP)    ;  push 15 regs
  489.         MOVE.L    SP, -(SP)            ;   push sig context ptr
  490.         MOVE.L    CurrentA5, A5        ;    for C variable access
  491.         JSR        e_raise_guts        ;    called in supervisor mode!!!!!
  492.         ADDQ.L    #4, SP                ;   drop sig context ptr
  493.         FSAVE    -(SP)                ; dump the FPU
  494.         ; M68881 check not necessary
  495.         ; MOVEQ    #$18, D0            ; frame size for M68881
  496.         ; CMP.B    D0, 1(SP)            ; FPU frame size
  497.         ; BEQ.S    @rtn                ; if M68881, we're done
  498.         MOVE.B    (SP), D0            ; null frame?
  499.         BEQ.S    @rtn                ; if so, done
  500.         CLR.L    D0                    ; get frame size
  501.         MOVE.B    1(SP), D0            ; into D0
  502.         BSET    #3, (SP, D0)        ; set EXC_PEND bit of BIU
  503. @rtn:    FRESTORE (SP)+                ; load the FPU
  504.         MOVEM.L    (SP)+, D0-D7/A0-A6    ;  pop  15 regs
  505.         ADDQ.L    #4, SP                ; drop sig
  506.         RTE                            ; return
  507.         ;
  508. extern init_TRAPS:
  509.         LEA.L    @handleTRAP, A0
  510.         MOVE.L    A0, 0x14            ; dbz
  511.         MOVE.L    A0, 0x1C            ; TRAPcc
  512.         LEA.L    @handleFPU, A0        ;                12Feb92  e
  513.         MOVE.L    A0, 0xC8            ; FPdbz
  514.         MOVE.L    A0, 0xD4            ; FPovf
  515.         MOVE.L    A0, 0xCC            ; FPund
  516.         ; for Virtual Memory Mode                    10Feb92  e
  517.         ; this is not strictly necessary, 
  518.         ;   but speeds things up a bit
  519.         MOVEQ    #0, D0                ; in VM Mode?
  520.         DC.W    0xA08D                ; _DebugUtil
  521.         SUBQ.L    #8, D0                ; VM?
  522.         BLT.S    @punt                ; skip if not
  523.         MOVEQ    #8, D0                ; enter supervisor mode
  524.         DC.W    0xA08D                ; _DebugUtil
  525.         LEA.L    @handleTRAP, A0
  526.         MOVEC    VBR, A1
  527.         MOVE.L    A0, 0x14(A1)        ; dbz
  528.         MOVE.L    A0, 0x1C(A1)        ; TRAPcc
  529.         LEA.L    @handleFPU, A0        ;                12Feb92  e
  530.         MOVE.L    A0, 0xC8(A1)        ; FPdbz
  531.         MOVE.L    A0, 0xD4(A1)        ; FPovf
  532.         MOVE.L    A0, 0xCC(A1)        ; FPund
  533.         MOVE    D0, SR                ;  exit supervisor mode
  534. @punt:
  535.     }
  536. }
  537.  
  538. void
  539. e_raise(int sig)
  540.     {
  541.     asm {
  542.         /* fix the stack frame to look like an exception frame */
  543.         MOVE.W    #0, -(SP)            ; dummy SR
  544.         MOVE.L    6(SP), -(SP)        ; sig
  545.         MOVEM.L    D0-D7/A0-A6, -(SP)    ; 15 regs
  546.         MOVE.L    SP, -(SP)            ;  sig context ptr
  547.         MOVE.L    CurrentA5, A5        ; for C variable access
  548.         JSR        e_raise_guts
  549.         ADDQ.L    #4, SP                ; drop context ptr
  550.         MOVEM.L    (SP)+, D0-D7/A0-A6    ; 15 regs
  551.         ADDQ.L    #6, SP                ; drop dummy SR & sig
  552.     }
  553.     if (sig <= __NSIG)
  554.         signal(sig, e_raise);
  555. }
  556.  
  557. void
  558. e_signal(int i, __sig_func_e f)
  559. {
  560.     
  561.     if (i <= 0 || i > __NSIG_e) {
  562.         errno = EINVAL;
  563.         return;
  564.     }
  565.     e_sig[i] = f;
  566.     if (i <= __NSIG)
  567.         signal(i, e_raise);
  568. }
  569.  
  570. void
  571. e_restart_handler(int sig)
  572.     {
  573.     signal(sig, e_restart_handler);
  574.     longjmp(restartJmpBuf, 2);
  575. }
  576.  
  577. /* end of MacOS.dep.c */
  578.